জাভার জেনেরিক্স Compile-time Type Checking সাপোর্ট করে, কিন্তু Runtime Type Checking সরাসরি জেনেরিক টাইপে সম্ভব নয় কারণ জাভার Type Erasure মেকানিজম জেনেরিক টাইপের তথ্য রানটাইমে সরিয়ে ফেলে। তবে, Reflection API ব্যবহার করে জেনেরিক টাইপ সম্পর্কিত কিছু তথ্য রানটাইমে পাওয়া সম্ভব।
Reflection এবং Generics: Runtime Type Checking
Type Erasure সমস্যার কারণ
Type Erasure এর কারণে, জেনেরিক টাইপ রানটাইমে অপ্রাসঙ্গিক হয়ে যায়। উদাহরণ:
import java.util.ArrayList;
import java.util.List;
public class TypeErasureExample {
public static void main(String[] args) {
List<String> stringList = new ArrayList<>();
List<Integer> intList = new ArrayList<>();
System.out.println(stringList.getClass() == intList.getClass()); // Output: true
}
}
কারণ:
List<String>এবংList<Integer>উভয় ক্ষেত্রেই রানটাইমে ক্লাসের টাইপ তথ্য মুছে ফেলা হয়। ফলে, উভয় লিস্ট একইArrayListটাইপে পরিণত হয়।
Reflection দিয়ে Generics তথ্য নির্ণয়
Reflection API ব্যবহার করে ক্লাস বা ফিল্ডের জেনেরিক টাইপের তথ্য রানটাইমে জানা যায়।
উদাহরণ ১: ফিল্ডের জেনেরিক টাইপ চেক করা
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
public class GenericReflectionExample {
private List<String> stringList;
public static void main(String[] args) throws NoSuchFieldException {
Field field = GenericReflectionExample.class.getDeclaredField("stringList");
// Check if the field has a generic type
Type genericType = field.getGenericType();
if (genericType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericType;
Type[] typeArguments = parameterizedType.getActualTypeArguments();
// Print the generic type arguments
for (Type type : typeArguments) {
System.out.println("Generic type: " + type.getTypeName());
}
}
}
}
আউটপুট:
Generic type: java.lang.String
উদাহরণ ২: মেথডের জেনেরিক টাইপ চেক করা
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
public class GenericMethodReflection {
public List<Integer> getIntegerList() {
return null;
}
public static void main(String[] args) throws NoSuchMethodException {
Method method = GenericMethodReflection.class.getMethod("getIntegerList");
// Get the generic return type
Type genericReturnType = method.getGenericReturnType();
if (genericReturnType instanceof ParameterizedType) {
ParameterizedType parameterizedType = (ParameterizedType) genericReturnType;
Type[] typeArguments = parameterizedType.getActualTypeArguments();
// Print the generic type arguments
for (Type type : typeArguments) {
System.out.println("Generic return type: " + type.getTypeName());
}
}
}
}
আউটপুট:
Generic return type: java.lang.Integer
Generics এ Runtime Type Checking করার জন্য কাস্টম কোড
যেহেতু জেনেরিক টাইপ সরাসরি চেক করা যায় না, তাই কাস্টম লজিক ব্যবহার করা যেতে পারে।
উদাহরণ: লিস্টের কনটেন্ট টাইপ চেক করা
import java.util.ArrayList;
import java.util.List;
public class RuntimeTypeCheck {
public static <T> boolean isOfType(List<?> list, Class<T> clazz) {
for (Object obj : list) {
if (!clazz.isInstance(obj)) {
return false;
}
}
return true;
}
public static void main(String[] args) {
List<String> stringList = new ArrayList<>();
stringList.add("Hello");
stringList.add("World");
List<Integer> intList = new ArrayList<>();
intList.add(1);
intList.add(2);
System.out.println(isOfType(stringList, String.class)); // Output: true
System.out.println(isOfType(intList, String.class)); // Output: false
}
}
Reflection এবং Annotated Generics
Reflection দিয়ে Annotated Generics এর টাইপও নির্ধারণ করা সম্ভব।
উদাহরণ: Generics এর সাথে Annotated ফিল্ড চেক করা
import java.lang.reflect.Field;
import java.util.List;
public class AnnotatedGenericsExample {
private List<@Deprecated String> annotatedList;
public static void main(String[] args) throws NoSuchFieldException {
Field field = AnnotatedGenericsExample.class.getDeclaredField("annotatedList");
System.out.println("Field: " + field.getName());
System.out.println("Annotated type: " + field.getAnnotatedType());
}
}
আউটপুট:
Field: annotatedList
Annotated type: java.util.List<@java.lang.Deprecated java.lang.String>
Reflection ব্যবহার করার সুবিধা
- জেনেরিক টাইপের তথ্য পেতে: Type Erasure এর সীমাবদ্ধতা কাটিয়ে জেনেরিক টাইপ সম্পর্কিত তথ্য জানা যায়।
- রানটাইম যাচাইকরণ: জেনেরিক টাইপ চেকিং এবং ডায়াগনস্টিক তৈরি করতে কার্যকর।
- ডায়নামিক প্রোগ্রামিং: ডায়নামিক টাইপ-ভিত্তিক অপারেশন এবং ডিবাগিং সহজ হয়।
জাভার জেনেরিক্স রানটাইম টাইপ ইনফরমেশন সরিয়ে ফেলে (Type Erasure), তবে Reflection API ব্যবহার করে জেনেরিক টাইপ সম্পর্কিত তথ্য রানটাইমে নির্ণয় করা সম্ভব। এটি টাইপ ইনফরমেশন অ্যাক্সেস, যাচাইকরণ এবং ডায়নামিক প্রোগ্রামিংয়ে গুরুত্বপূর্ণ ভূমিকা পালন করে।
Read more